home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr40 / x1j4_src.zip / TNL7B1.C < prev    next >
Text File  |  1995-02-12  |  31KB  |  837 lines

  1. /*****************************************************************************/
  2. /*                                              */
  3. /*                                         */
  4. /*    *****              *****                      */
  5. /*     *****            *****                         */
  6. /*       *****          *****                         */
  7. /*         *****        *****                         */
  8. /*  ***************      ***************                     */
  9. /*  *****************    *****************                     */
  10. /*  ***************      ***************                     */
  11. /*         *****        *****       TheNet                    */
  12. /*       *****          *****       Portable. Compatible.         */
  13. /*     *****            *****       Public Domain             */
  14. /*    *****              *****    NORD><LINK                  */
  15. /*                                         */
  16. /* This software is public domain ONLY for non commercial use                */
  17. /*                                                                           */
  18. /*                                         */
  19. /*****************************************************************************/
  20.  
  21. /* Level 7B, Befehlsinterpreter, Befehle                     */
  22. /* Version 1.01                                   */
  23. /* Hans Georg Giese, DF2AU, Hinter dem Berge 5, 3300 Braunschweig         */
  24. /* 08-MAY-88                                     */
  25.  
  26. /* Modified by G8KBB - Jan 91                              */
  27. /*      - conditionally exclude ccpcq() if NOCQ is defined                   */
  28. /*      - disable downlink connects if NODOWNLINK is defined                 */
  29. /*      - Use of register keyword for code reduction                         */
  30. /*      - replace seades() by iscall() - function name change !              */
  31. /*      - Use all.h header file                                              */
  32. /*      - add a polite error if CQ not enabled                               */
  33. /*      - give error msg in 'nodes' cmd when node name not recognised        */
  34. /*        and do it conditionally on MODIFIED                                */
  35. /*      - conditionally, put front-end to connect to trap 'c' with no dest   */
  36. /*      - conditionally, include MODE command and reuse common code in PARAM */
  37. /*      - make reset do cold or warmstart conditionally on parameter given   */
  38. /*      - move common code from LOW and HIGH commands to one routine         */
  39. /*      - correct bug in ccpide() conditionally on MODIFIED                  */
  40. /*      - make connect with no parameters go to BBS or HOST on ctobbs setting*/
  41. /*      - conditionally exclude HI and LOW commands on NOHILOW               */
  42. /*      - Add connect in progress info message to user                       */
  43. /*      - Add ACL functions into connect command                             */
  44. /*      - Remove spurious '== 1' and similar constructs to simplify          */
  45. /*      - Add digipeat downlink control into connect command                 */
  46.  
  47. /* This half of the command interpreter functions contains the following
  48.  * commands :
  49.  *     Connect        CQ         Ident       Nodes        Parms
  50.  *     Mode           MTU        Meter       Routes       Reset
  51.  *     Low            High       Sysop       Users
  52.  */
  53.  
  54. /*
  55.  * September 1993 - released as TheNet X-1J
  56.  */
  57.  
  58. #include "all.h"
  59. #include "tntyp.h"        /* Definition der Typen                 */
  60. #include "tnl7be.h"        /* externe Definitionen                 */
  61.  
  62. char noconnect[] = "Cannot connect. Sorry.";
  63. char linktxt[] = "Link";
  64.  
  65. /*---------------------------------------------------------------------------*/
  66. VOID    ccpcon()        /* CONNECT Befehl                 */
  67. #ifdef MODIFIED            /* conditionally, put filter in front of 'C' */
  68. {                /* command to bar it by sysop but let the    */
  69.   if( clicnt == 0 )        /* also, if no parameter is given to connect */
  70.   {
  71.     switch( ctobbs )
  72.     {
  73.       case 0:
  74.             ccphst();    /* do the 'host' command                     */
  75.             break;
  76.       case 1:
  77.             ccpbbs();    /* do the BBS command                        */
  78.             break;
  79.       case 2:
  80.             ccpdxc();   /* do the DXcluster command */
  81.             break;
  82.       default:
  83.             ccp_con();
  84.     }
  85.   }
  86.   else
  87.       ccp_con();        /* else do the original 'connect' command !  */
  88. }
  89.  
  90. ccp_con()            /* original connect command renamed ccp_con()*/
  91. #endif
  92.   {
  93.   char       call[7];        /* User Call                     */
  94.   char       digil[57];        /* Downlink Digiliste                 */
  95.   char       node[6];        /* Ziel Node                     */
  96.   char       *cpoisa;        /* Temp fuer clipoi                 */
  97.   unsigned ccntsa;        /* Temp fuer clicnt                 */
  98.   unsigned is_call;        /* Ergebniss der Suche nach Call         */
  99.   unsigned isnode;        /* Ergebniss der Suche nach Node         */
  100.   register unsigned cnt;    /* Scratch Zaehler                 */
  101.   register usrtyp   *usrpoi;    /* aktueller User beim Suchen             */
  102.   l2ltyp   *frelnk;        /* freier lnkpoi Platz                 */
  103.   register l2ltyp   *p_cblk;    /* Partner lnkpoi Block                 */
  104.  
  105.   if (!ismemr()) return;    /* noch Platz?                      */
  106.  
  107.  
  108.   if (clicnt != 0)        /* ohne Parameter -> Host connecten         */
  109.    {
  110.     cpoisa = clipoi;        /* Parameter des Aufrufs retten             */
  111.     ccntsa = clicnt;
  112.     isnode = getide(node);    /* Node angegeben?                 */
  113.     clipoi = cpoisa;        /* Aufrufparameter zurueck             */
  114.     clicnt = ccntsa;
  115.  
  116.     if (
  117.        (((is_call = ((getcal(&clicnt, &clipoi, VCpar, call) == 1) &&
  118.                     (getdig(&clicnt, &clipoi, 0, digil) != -1))
  119.                     ) /* == 1 */)
  120.         && (digil[0] == 0)
  121.         && (iscall(call) == 1))
  122.         || ((isnode == 1) && (isidnt(node) /* == 1*/ )))
  123.        {
  124.  
  125. /*=== Node soll connected werden ============================================*/
  126.         for (cnt = 0, cirpoi = cirtab; cnt < NUMCIR; ++cnt, ++cirpoi)
  127.          {                /* freien Platz in CIRTAB suchen     */
  128.           if (cirpoi->state3 == 0) break;
  129.          }
  130. #ifdef ACL
  131.         if( (acl_mask & ACL_BAR_L4_OG ) &&
  132.             (acl_entry( despoi->nodcal ) & ACL_BAR_L4_OG ))
  133.           putmsg(noconnect);
  134.       else
  135. #endif
  136.         if (cnt != NUMCIR )        /* Erfolg dabei?             */
  137.          {
  138.           userpo->cblk_p = (l2ltyp *) cirpoi;    /* in User Block eintragen   */
  139.           userpo->typ_p = 4;        /* und Usertyp eintragen         */
  140.           userpo->status = 2;        /* Staus: connect requested         */
  141.           cpyid(cirpoi->downca, despoi->nodcal);
  142.           cpyid(cirpoi->upcall, usrcal);/* User Call merken             */
  143.           cirpoi->l3node = despoi;    /* CIRTAB Eintrag mit Userdaten         */
  144.           newcir();            /* Circuit aufbauen             */
  145.          }
  146.         else puttfu("Circuit");        /* kein Platz: melden             */
  147.         return;
  148.        }
  149.  
  150. /*=== User soll connected werden ============================================*/
  151.     if (is_call == 1)            /* gueltiges Call?             */
  152.      {
  153. #ifdef NODOWNLINK
  154.     putmsg("Downlink is not possible from this switch\15");
  155. #else
  156.                     /* Antwort auf CQ-Ruf?             */
  157.       for (usrpoi = (usrtyp *) usccpl.lnext;
  158.            (usrtyp *) &usccpl != usrpoi;
  159.             usrpoi = usrpoi->unext)
  160.        {                /* Userliste absuchen             */
  161.         if ((usrpoi->status == 2)    /* Status muss stimmen             */
  162.           &&(usrpoi->typ_p == 2)    /* gesuchter Partner muss stimmen    */
  163.           &&((p_cblk = usrpoi->cblk_p)->state == 0)) /* und noch kein L2     */
  164.          {
  165.          if (cmpid(p_cblk->srcid, call) /*== 1*/) /* und eigenes Call         */
  166.           {
  167.            disusr(p_cblk, 2);        /* dann aus CCP entfernen         */
  168.            for (ptcrdp = ptcrdl; ptcrdp->luserl != 0; ptcrdp += 2)
  169.             ;                /* freier Eintrag links             */
  170.            makcon(usrpoi);        /* Verbindung herstellen         */
  171.            ++ptcrdp;            /* auf rechte Seite             */
  172.            frelnk = (l2ltyp *) userpo;
  173.            userpo = usrpoi;
  174.            makcon(usrpoi = (usrtyp *) frelnk);    /* zweite Seite              */
  175.            kilusr();            /* Partner loeschen             */
  176.            userpo = usrpoi;
  177.            kilusr();            /* eigenen Eintrag loeschen         */
  178.            return;
  179.           }
  180.          }
  181.        }
  182.                                         /* Connect in L2 absetzen         */
  183.       invsid();                /* SSID aendern                 */
  184.       for (p_cblk = 0, cnt = 0, lnkpoi = lnktbl; /* freien Eintrag finden    */
  185.            cnt < MAXL2L; ++cnt, ++lnkpoi)
  186.        {
  187.         if (lnkpoi->state != 0)        /* Eintrag leer?             */
  188.          {
  189.           if ((cmpid(lnkpoi->srcid, usrcal) /* == 1 */ )
  190.             && (cmpid(lnkpoi->dstid, call) /* == 1 */ ))
  191.            {
  192.             msgfrm('D', lnkpoi, 2, dmmsg); /* nicht gleiche Partner 2-mal    */
  193.             return;
  194.            }
  195.          }
  196.         else                /* leerer Eintrag gefunden:         */
  197.          {
  198.           if ((! p_cblk) && (lnkpoi->srcid[0] == 0))
  199.            p_cblk = lnkpoi;        /* den ersten merken             */
  200.          }
  201.         }
  202. #ifdef ACL
  203.       if( (acl_mask & ACL_BAR_L2_OG) && (acl_entry( call ) & ACL_BAR_L2_OG ))
  204.           putmsg(noconnect);
  205.       else
  206. #endif
  207. #ifdef MODIFIED
  208.       if( ( no_digi & 2 ) && *digil )
  209.           putmsg("Sorry - no digi");
  210.       else
  211. #endif
  212.       if (p_cblk != 0) {        /* freier Platz da?             */
  213.         lnkpoi = p_cblk;        /* merken                 */
  214.         setl2b();            /* L2 Block initialisieren         */
  215.         cpyid(lnkpoi->dstid, call);    /* Partner Call                 */
  216.         cpyidl(lnkpoi->viaid, digil);    /* Digipeater                 */
  217.         lnkpoi->liport = 0;        /* Port ist HDLC             */
  218.         newlnk();            /* an Level2 melden             */
  219.         }
  220.       else {                /* alles voll                 */
  221.         puttfu( linktxt );            /* melden                 */
  222.         }
  223. #endif
  224.     }
  225.     else invcal();
  226.     return;
  227.     }
  228.  
  229. /*=== Host soll connected werden ============================================*/
  230.   for (cnt = 0, hstusr = hstubl;    /* alle Hostkanaele absuchen         */
  231.        cnt < MAXHST;
  232.        ++cnt, ++hstusr) {
  233.     if (! hstusr->conflg)        /* dieser Kanal belegt?             */
  234.       break;
  235.     }
  236.   if (cnt != MAXHST) {            /* freien Kanal gefunden?         */
  237.     userpo->cblk_p = (l2ltyp *) hstusr;        /* Host als Partner eintragen*/
  238.     userpo->typ_p = 0;            /* Usertyp ist Host             */
  239.     userpo->status = 2;            /* neuer Status: connect requested   */
  240.     cpyid(hstusr->call, usrcal);    /* Usercall in Hostblock eintragen   */
  241.     hstreq();                /* Request an Hostinterface leiten   */
  242.     return;
  243.     }
  244.   else puttfu("Host");            /* kein Kanal frei             */
  245. }
  246.  
  247. #ifndef NOCQ
  248. /*---------------------------------------------------------------------------*/
  249. ccpcq()                /* CQ-Ruf starten                 */
  250.   {
  251.   register unsigned cnt;        /* Scartch Zaehler             */
  252.   register mhtyp    *mbhd;        /* Buffer fuer Meldung             */
  253.  
  254.   if (ismemr() /* == 1 */)        /* Platz genug?                 */
  255.    {
  256.     for (cnt = 0, lnkpoi = lnktbl; cnt < MAXL2L; ++cnt, ++lnkpoi)
  257.      {                    /* freien Platz in L2-Liste suchen   */
  258.       if ((lnkpoi->state == 0) && (lnkpoi->srcid[0] == 0))
  259.         break;
  260.      }
  261.     if (cnt < MAXL2L)
  262.      {
  263.       invsid();                /* SSID umdrehen             */
  264.       setl2b();                /* L2 Kontrollblock initialisieren   */
  265.       if (cqen /* == 1 */)        /* CQ-Ruf zulaessig?             */
  266.        {
  267.         (mbhd = (mhtyp *) allocb())->pid = PID_NO_L3;    /* PID setzen         */
  268.         while (clicnt != 0)        /* Rest der Zeile ist Meldung         */
  269.          {
  270.           putchr(*clipoi, mbhd);    /* umkopieren                 */
  271.           nxtcli();
  272.          }
  273.         putchr(0x0d, mbhd);        /* Zeilenende anhaengen             */
  274.         rwndmb(mbhd);            /* Pointer auf Null             */
  275.         sdui(cqdil, cqdest, usrcal, 0, mbhd); /* senden                 */
  276.         dealmb(mbhd);            /* Buffer wieder freigeben         */
  277.        }
  278.       else
  279.           putmsg("Sorry, CQ is not enabled");    /* Error message     */
  280.      }
  281.     else                /* Tabelle ist voll             */
  282.       puttfu( linktxt );            /* melden                 */
  283.    }
  284.   }
  285. #endif
  286.  
  287. /*---------------------------------------------------------------------------*/
  288. VOID    ccpide()        /* Befehl INFO                     */
  289. {
  290.   register mhtyp *bufpoi;            /* Buffer fuer Meldung         */
  291.   register unsigned chaptr;
  292.  
  293. #ifdef MODIFIED
  294.   settxt( infmsg, 159 );
  295. #else
  296.   if (issyso() == TRUE)                /* Sysop setzt Zusatz?         */
  297.    {
  298.     chaptr = 0;
  299.     while (clicnt != 0)
  300.      {
  301.       infmsg[chaptr++] = *clipoi;
  302.       nxtcli();
  303.       if( chaptr == 159 )        /* if max length of infmsg is reached*/
  304.           break;            /* then stop storing.                */
  305.      }
  306.     infmsg[chaptr] = 0;
  307.    }
  308. #endif
  309.  
  310.   bufpoi = putals(DEFINF);            /* Info mit Header         */
  311.   putchr('\015', bufpoi);
  312.   putstr(infmsg, bufpoi);            /* Zusatzinfo             */
  313.   seteom(bufpoi);                /* Endekennung dran         */
  314.   }
  315.  
  316. /*---------------------------------------------------------------------------*/
  317. VOID    ccpnod()        /* NODES Befehl                     */
  318.   {
  319.   char       newcal[7];        /* neues Call                     */
  320.   char       niden[6];        /* neuer Ident                     */
  321.   char     *cpoisa;        /* temp fuer clipoi                 */
  322.   BOOLEAN  alles;        /* versteckte Nodes auch zeigen             */
  323.   unsigned nobc;        /* neuer Abwesenheitszaehler             */
  324.   unsigned wegcnt;        /* Zaehler fuer Wege in Ausgabe             */
  325.   unsigned aender;        /* Aenderungsmode: + oder -             */
  326.   register unsigned is_call;    /* Ergebniss des Tests auf gueltiges Call    */
  327.   register unsigned isnode;    /* Ergebniss des Tests auf gueltigen Node    */
  328.   unsigned ccntsa;        /* temp fuer clicnt                 */
  329.   BOOLEAN  neupar;        /* neue Parameter in der Zeile             */
  330.   unsigned cnt;            /* Scratch Zaehler                 */
  331.   unsigned leer;        /* Leerzeichen bis zum naechsten Node         */
  332.   register mhtyp *bufpoi;    /* Buffer fuer Meldung an User             */
  333.   wegtyp   *actweg;        /* aktueller Weg der Ausgabe             */
  334.   nbrtyp   *nabar;        /* Nachbar fuer aktuellen Node             */
  335.  
  336.   alles = FALSE;        /* default: keine versteckten Nodes         */
  337.   if (clicnt != 0)        /* mit Argument aufgerufen?                */
  338.    {
  339.     cpoisa = clipoi;        /* Befehlszeile retten                    */
  340.     ccntsa = clicnt;
  341.     isnode = getide(niden);    /* Test auf Node Namen                 */
  342.     clipoi = cpoisa;        /* Befehlszeile zurueck                 */
  343.     clicnt = ccntsa;
  344. #ifdef MODIFIED
  345.     is_call = getcal(&clicnt, &clipoi, 1, newcal); /* Test auf Call         */
  346. #else
  347.     is_call = getcal(&clicnt, &clipoi, VCpar, newcal); /* Test auf Call         */
  348. #endif
  349.     clipoi = cpoisa;        /* Befehlszeile zurueck                 */
  350.     clicnt = ccntsa;
  351.  
  352.     while (clicnt != 0)
  353.      {
  354.       if (*clipoi == ' ') break;
  355.       nxtcli();
  356.      }
  357.  
  358.     if ((is_call == 1)        /* alle Nodes oder was spezielles gefragt?   */
  359.       || (isnode != -1))
  360.      {
  361.       neupar = FALSE;            /* default: keine neuen Parameter    */
  362.       if ((issyso() /* == 1 */)        /* nur Sysop darf aendern         */
  363.         && (is_call == 1))        /* wenn er ein Call angibt         */
  364.        {
  365.         --clicnt;            /* Aenderungsmode uebergehen         */
  366.         if (((aender = *clipoi++) == '+') /* nur + oder - erlaubt         */
  367.           || (aender == '-'))
  368.          {
  369.  
  370. /*=== Node Parameter aendern ================================================*/
  371.           if ((skipspace() /* == 1*/ ) /* Parameter holen         */
  372.             && ((isnode = getide(niden)) != -1)) /* Ident             */
  373.            {
  374.             if (getqua() /* == 1 */)        /* Qualitaet holen         */
  375.              {
  376.               if ((skipspace() /* == 1 */)
  377.               && ((nobc = nextnumber() ) <= 255))
  378.                {
  379.                 if (getpar() /* == 1 */) 
  380.                    neupar = TRUE;         /* Port, Digis, Nachbar    */
  381.                }
  382.              }
  383.            }
  384.          }
  385.        }
  386.       else if (isnode == 0) alles = 1; /* Sternchen eingegeben             */
  387.  
  388.       if (neupar /* == TRUE */) {        /* neue Werte spezifiziert   */
  389.         if (chgnod(aender, nobc, nquali, nport, ndigi, ncall, niden, newcal)
  390.             == 0) {
  391.           puttfu("Routing");        /* hat nicht geklappt, Ende         */
  392.           return;
  393.           }
  394.         }
  395.       if (((is_call == TRUE) && (iscall(newcal) /* == 1 */)) /*gueltiges Call*/
  396.        || ((isnode == TRUE) && (isidnt(niden) /* == 1*/))) { /* Node?         */
  397.         putnod(bufpoi = putals("Routes to: ")); /* gueltig:             */
  398.  
  399.         for (wegcnt = 0; wegcnt < despoi->wege; ++wegcnt)
  400.          {                /* alle Wege zeigen             */
  401.           nabar = (actweg = &despoi->weg[wegcnt])->nachba;
  402.           putstr((((despoi->actrou != 0) && (despoi->wegnr == wegcnt)) ?
  403.             "\015> " : "\015  "), bufpoi); /* aktiven Weg markieren         */
  404. #ifdef MODIFIED
  405.           putnum_and_space((actweg->qualit) &0xff, bufpoi);
  406. #else
  407.           putnum((actweg->qualit) &0xff, bufpoi);
  408.           putchr(' ', bufpoi);
  409. #endif
  410.           putnum((actweg->obscnt) &0xff, bufpoi);
  411.           putnbr(nabar, bufpoi);    /* Nachbarn Zeigen             */
  412.          }
  413.  
  414.         seteom(bufpoi);            /* Ende anhaengen             */
  415.         return;
  416.         }
  417. #ifdef MODIFIED
  418.         else if( alles == FALSE )         /* if node requested    */
  419.         {                    /* that is not known,   */
  420.             putmsg("Unknown node." );         /* then give an error   */
  421.             return;                /* rather than nodes    */
  422.         }
  423. #endif
  424.       }
  425.     }
  426.  
  427. /*=== Nodes anzeigen ========================================================*/
  428.   bufpoi = putals("Nodes:");        /* Kopfzeile holt Buffer         */
  429.   cnt = 0;                /* Nummer des Eintrages             */
  430.   for (despoi = (nodtyp *) destil.lnext;        /* gesamte Liste             */
  431.        (nodtyp *) &destil != despoi;
  432.        despoi = (nodtyp *) despoi->nodlnk.lnext) {
  433.     if (despoi->nodcal[0] != 0) {    /* Eintrag definiert?             */
  434.       if (
  435.            ((despoi->nodide[0] != '#') || (alles /*== TRUE*/))
  436. #ifdef MODIFIED
  437.            && (( no_slime & 1 ) == 0 || despoi->nodide[0] != ' ' )
  438. #endif
  439.          )                 /* auch versteckte Nodes zeigen?     */
  440.       {        
  441. #ifdef MODIFIED
  442.         if( clicnt && *clipoi == '*' )
  443.         {
  444.           putchr('\015', bufpoi);
  445.           bufpoi->l4time = bufpoi->putcnt;
  446.           putnod(bufpoi); /* gueltig:             */
  447.           putspa(17, bufpoi);        /* Abstand zum Nachbarn             */
  448.           for (wegcnt = 0; wegcnt < despoi->wege; ++wegcnt)
  449.           {                /* alle Wege zeigen             */
  450.             if( wegcnt > 0 )
  451.               putspa(22, bufpoi);    /* Abstand zum Nachbarn             */
  452.             bufpoi->l4time = bufpoi->putcnt;
  453.             nabar = (actweg = &despoi->weg[wegcnt])->nachba;
  454.             putstr((((despoi->actrou != 0) && (despoi->wegnr == wegcnt)) ?
  455.               "> " : "  "), bufpoi); /* aktiven Weg markieren         */
  456.             putnum_and_space((actweg->qualit) &0xff, bufpoi);
  457.             putnum_and_space((actweg->obscnt) &0xff, bufpoi);
  458.             putnum_and_space((nabar->nbrpor) &0xff, bufpoi);
  459.             putid(nabar->nbrcal, bufpoi);    /* Nachbarn Zeigen             */
  460.           }
  461.         }
  462.         else
  463.         {
  464. #endif
  465.         if ((cnt++ & 0x03) == 0)    /* 4 Nodes in eine Zeile         */
  466.           putchr('\015', bufpoi);
  467.         bufpoi->l4time = bufpoi->putcnt;
  468.         putnod(bufpoi);            /* Node ausgeben             */
  469.         putspa(19, bufpoi);        /* Abstand zum Nachbarn             */
  470. #ifdef MODIFIED
  471.        }
  472. #endif
  473.     } } }
  474.   seteom(bufpoi);            /* Endekennung anhaengen         */
  475.   }
  476.  
  477. /*---------------------------------------------------------------------------*/
  478. #ifdef MODIFIED
  479. /*
  480.  * move the param code to a common routine to allow Param and Mode to share it
  481.  */
  482.  
  483. VOID ccppar()
  484. {
  485.     ccp_par( partab, (sizeof(partab) / sizeof(struct param)));
  486. }
  487.  
  488. VOID ccpmod()
  489. {
  490.     ccp_par( modtab, (sizeof(modtab) / sizeof(struct param)));
  491. }
  492.  
  493. #ifdef MANAGED
  494. VOID ccpaud()
  495. {
  496.     ccp_par( audtab, (sizeof(audtab) / sizeof(struct param)));
  497. }
  498. #endif
  499.  
  500. #ifdef MOD_MTU
  501. VOID ccpmtu()
  502. {
  503.     ccp_par( mtutab, (sizeof(mtutab) / sizeof(struct param)));
  504. }
  505. #endif
  506.  
  507. #ifdef METERS
  508. VOID ccpmet()
  509. {
  510.     ccp_par( mettab, (sizeof(mettab) / sizeof(struct param)));
  511. }
  512. #endif
  513.  
  514. #ifdef PK96
  515. VOID ccpbra()
  516. {
  517.     ccp_par( bratab, (sizeof(bratab) / sizeof(struct param)));
  518. }
  519. #endif
  520.  
  521. VOID    ccp_par(table, tablesize)        /* PARMS Befehl                     */
  522. partyp *table;
  523. unsigned tablesize;
  524.   {
  525.   unsigned laenge;        /* Laenge der Zeile bisher             */
  526.   register unsigned newval;    /* neuer Wert des Parameters             */
  527.   unsigned parnum;        /* Nummer des aktuellen Parameters         */
  528.   register mhtyp *bufpoi;    /* Message Buffer                 */
  529.   register partyp *parpoi;    /* Pointer auf aktuellen Parameter         */
  530.  
  531.   bufpoi = putals("");                /* Kopfzeile             */
  532.  
  533.   /* firstly, check for /parm value syntax, and if found handle it.
  534.    * also, trash any remaining line after that before falling thru
  535.    * into the old code
  536.    */
  537.   if( issyso() && *clipoi == '/' )
  538.   {
  539.       nxtcli();
  540.       if( clicnt && ( parnum = nextnumber() -1 ) < tablesize 
  541.           && skipspace() )
  542.       {
  543.           newval = nextnumber();
  544.           parpoi = &table[parnum];
  545.           if( newval >= parpoi->minimal && newval <= parpoi->maximal )
  546.               *(parpoi->paradr) = newval;
  547.       }
  548.     clicnt = 0;
  549.   }
  550.  
  551.   for (laenge = 0, parnum = 0, parpoi = table;
  552.        parnum < tablesize;
  553.        ++parnum, ++parpoi)            /* alle Parameter         */
  554.   {
  555.     if (issyso())            /* Sysop am anderen Ende?    */
  556.     {
  557.       if (*clipoi != '*')            /* Wert aendern?         */
  558.       {
  559.         newval = nextnumber();    /* neuen Wert holen         */
  560.         if ((newval >= parpoi->minimal) && (newval <= parpoi->maximal))
  561.           *(parpoi->paradr) = newval;
  562.         else 
  563.           clicnt = 0;            /* Fehler: Rest vergessen    */
  564.       }
  565.       else                    /* Parameter bleibt:         */
  566.         nxtcli();                /* das Sternchen verbrauchen */
  567.      }
  568.     if ((bufpoi->putcnt - laenge) > 72)
  569.      {
  570.       putchr('\15', bufpoi);            /* neue Zeile             */
  571.       laenge = bufpoi->putcnt;
  572.      }
  573.     else putchr(' ', bufpoi);
  574.  
  575.     putnum(*(parpoi->paradr), bufpoi);        /* Wert ausgeben         */
  576.    }
  577.   seteom(bufpoi);        /* Endekennung anhaengen             */
  578.   }
  579.  
  580. #else
  581.  
  582. /* this is the original version of PARMS
  583.  */
  584.  
  585. VOID    ccppar()        /* PARMS Befehl                     */
  586.   {
  587.   unsigned laenge;        /* Laenge der Zeile bisher             */
  588.   register unsigned newval;    /* neuer Wert des Parameters             */
  589.   unsigned parnum;        /* Nummer des aktuellen Parameters         */
  590.   register mhtyp *bufpoi;    /* Message Buffer                 */
  591.   register partyp *parpoi;    /* Pointer auf aktuellen Parameter         */
  592.  
  593.   bufpoi = putals("");                /* Kopfzeile             */
  594.   for (laenge = 0, parnum = 0, parpoi = partab;
  595.        parnum < (sizeof(partab) / sizeof(struct param));
  596.        ++parnum, ++parpoi)            /* alle Parameter         */
  597.    {
  598.     if (issyso() == TRUE)            /* Sysop am anderen Ende?    */
  599.      {
  600.       if (*clipoi != '*')            /* Wert aendern?         */
  601.        {
  602.         newval = nextnumber();    /* neuen Wert holen         */
  603.         if ((newval >= parpoi->minimal) && (newval <= parpoi->maximal))
  604.          *(parpoi->paradr) = newval;
  605.        
  606.         else clicnt = 0;            /* Fehler: Rest vergessen    */
  607.        }
  608.       else                    /* Parameter bleibt:         */
  609.         nxtcli();                /* das Sternchen verbrauchen */
  610.      }
  611.     if ((bufpoi->putcnt - laenge) > 72)
  612.      {
  613.       putchr('\15', bufpoi);            /* neue Zeile             */
  614.       laenge = bufpoi->putcnt;
  615.      }
  616.     else putchr(' ', bufpoi);
  617.  
  618.     putnum(*(parpoi->paradr), bufpoi);        /* Wert ausgeben         */
  619.    }
  620.   seteom(bufpoi);        /* Endekennung anhaengen             */
  621.   }
  622. #endif
  623.  
  624. /*---------------------------------------------------------------------------*/
  625. VOID    ccprou()        /* ROUTES Befehl                 */
  626.   {
  627.   register unsigned mode;
  628.   register mhtyp    *mbhd;
  629.   register nbrtyp   *neigb;
  630.  
  631.   neigb = NULL;                    /* default: kein Nachbar     */
  632.   if (clicnt != 0)                /* aendern oder zeigen?         */
  633.    {
  634.     if (getpar())                /* Nachbardaten holen         */
  635.      {
  636.       neigb = (nbrtyp *) getnei(ndigi, ncall, nport);    /* existiert Nachbar?*/
  637.       if (issyso())                /* nur SYSOP darf aendern    */
  638.        {
  639.         mode = *clipoi;                /* Modus holen, merken         */
  640.         nxtcli();
  641.         if (getqua())                /* Qualitaet muss passen     */
  642.          {
  643.           if (mode == '+')            /* blockieren?             */
  644.            {
  645.             if (!neigb)                /* Nachbar existiert nicht?  */
  646.               neigb = (nbrtyp *) updnbr(ndigi, ncall, nport); /* erzeugen    */
  647.  
  648.             neigb->pathqu = nquali;        /* neue Daten setzen         */
  649.             neigb->locked = TRUE;        /* blockieren             */
  650.            }
  651.           else
  652.            {
  653.             if (mode == '-')            /* freigeben?             */
  654.              {
  655.               if (neigb != NULL)        /* nur wenn Nachbar existiert*/
  656.                {
  657.                 neigb->pathqu = nquali;        /* neue Daten setzen         */
  658.                 neigb->locked = FALSE;        /* nicht blockieren         */
  659.                 if (neigb->nbrrou == 0)        /* wenn keine Wege aktiv     */
  660.                  {
  661.                   dealoc(unlink(neigb));    /* Eintrag loeschen         */
  662.                   neigb = NULL;
  663.                  }
  664.                }
  665.              }
  666.            }
  667.          }
  668.        }
  669.      }
  670.    }
  671.   mbhd = putals("Routes:");            /* neue Daten zeigen         */
  672.   if (!neigb)                    /* kein Nachbar angegeben    */
  673.    {
  674.     for (neigb = (nbrtyp *) neigbl.lnext;
  675.         (nbrtyp *) &neigbl != neigb;
  676.          neigb = (nbrtyp *) neigb->nbrlnk.lnext)
  677.      {                        /* alle Wege zeigen         */
  678.       putrou(neigb, mbhd);
  679.      }
  680.    }
  681.   else
  682.     putrou(neigb, mbhd);            /* sonst Wege des Nachbarn   */
  683.  
  684.   seteom(mbhd);                    /* Ende Kennung anhaengen    */
  685.   }
  686.  
  687. /*---------------------------------------------------------------------------*/
  688. VOID    ccpres()        /* RESET Befehl                     */
  689.  {
  690.   if (userpo->sysflg == TRUE)    /* darf nur der Sysop         */
  691.    {
  692. #ifdef MODIFIED            /* conditionally, only do a coldstart */
  693.     if( clicnt /* > 0 */ )    /* if the reset command had a parameter */
  694. #endif
  695.     magicn = 0;            /* immer Kaltstart         */
  696.     reset();
  697.    }
  698.  }
  699.  
  700. #ifndef NOHILOW
  701. /*---------------------------------------------------------------------------*/
  702. VOID    ccplow()        /* LOW Befehl                     */
  703. {
  704.     LEDcontrol( FALSE );    /* common code removed to LEDcontrol()       */
  705. }
  706.  
  707. /*---------------------------------------------------------------------------*/
  708. VOID LEDcontrol( flag )
  709. int flag;
  710. {
  711.     if (issyso() == TRUE)        /* darf nur der Sysop         */
  712.     {
  713.         switch (nextnumber() )
  714.         {
  715.             case 0:
  716.                 CONled(flag);
  717.                 break;
  718.             case 1:
  719.                 STAled(flag);
  720.                 break;
  721.         }
  722.     }
  723. }
  724.  
  725. /*---------------------------------------------------------------------------*/
  726. VOID    ccphig()        /* HIGH Befehl                     */
  727. {
  728.     LEDcontrol( TRUE );
  729. }
  730.  
  731. #endif
  732.  
  733. /*---------------------------------------------------------------------------*/
  734. VOID    ccpsys()        /* SYSOP Befehl                     */
  735.   {
  736.   register unsigned cnt;    /* Scratch Zaehler                 */
  737.   register unsigned num;    /* Zufallszahl fuer Zeichenauswahl         */
  738.   register unsigned chk;    /* Check Zaehler                 */
  739.   mhtyp       *bufpoi;        /* Buffer fuer Passwort-Zahlen             */
  740.  
  741. #ifdef MANAGED
  742.   if( ( auditmask & 0x30 ) == 0x10 )
  743.     notify(L7id, 6, this_station(), NULL, ccpcm6, 5 );
  744. #endif
  745.   if (paswle != 0)                /* ohne Passwort kein Sysop  */
  746.    {
  747.     bufpoi = putals("");            /* Buffer besorgen         */
  748.     for (cnt = 0; cnt < 5; ++cnt)        /* 5 Zahlen ausgeben         */
  749.      {
  750.       do
  751.        {
  752.         do;
  753.         while (((num = random()) >= paswle)    /* Zufallszahl holen         */
  754.           || (paswrd[num] == ' '));        /* gueltiges Zeichen?         */
  755.         for (chk = 0; chk < cnt; ++chk)        /* keine Zahl doppelt         */
  756.          {
  757.           if ((userpo->paswrd[chk] & 0xff) == num) break;
  758.          }
  759.        }
  760.       while (cnt != chk);
  761.       userpo->paswrd[cnt] = num; /* neue Zahl merken                 */
  762.       putchr(' ', bufpoi);
  763.       putnum(num +1, bufpoi);    /* dem User mitteilen                 */
  764.      }
  765.     seteom(bufpoi);        /* Ende Kennung anhaengen             */
  766.     userpo->status = 3;        /* neuer Status: Passwort soll kommen         */
  767.    }
  768.   }
  769.  
  770. /*---------------------------------------------------------------------------*/
  771. VOID    ccpuse()        /* USERS Befehl                     */
  772.   {
  773.   register unsigned cnt;    /* Scratch Zaehler                 */
  774.   register mhtyp *bufpoi;    /* MBHD fuer Meldungen                 */
  775.   register usrtyp   *userp;    /* Userkontrollblock fuer CCP User         */
  776.   l2ltyp   *ucblk;        /* L2 User Kontrollblock             */
  777.  
  778.   bufpoi = putals(version);            /* Kopf                 */
  779.   putchr('(', bufpoi);
  780.   putnum(nmbfre, bufpoi);            /* freie Buffer             */
  781.   putchr(')', bufpoi);
  782.  
  783.                         /* erst die User mit Partner */
  784.   for (cnt = 0, ptcrdp = ptcrdl;        /* Patchcord Liste absuchen  */
  785.       cnt < ((NUMPAT +1) /2);
  786.       ++cnt, ptcrdp += 2)            /* nur "linke" Eintraege     */
  787.    {
  788.     if (ptcrdp->luserl != NULL)                /* Eintrag belegt?   */
  789.      {
  790.       putchr('\015', bufpoi);
  791.       bufpoi->l4time = bufpoi->putcnt;        /* Zeichen im Buffer merken  */
  792.       putuse('L', ptcrdp->luserl, ptcrdp->lusert, bufpoi); /* linke Seite    */
  793.       putspa(35, bufpoi);            /* Leerzeichen als Trennung  */
  794. #ifdef CHOKE_FLAGS
  795.       putstr( "  <", bufpoi );
  796.       block_code( ptcrdp->luserl, ptcrdp->lusert, bufpoi);
  797.       block_code( (ptcrdp+1)->luserl, (ptcrdp+1)->lusert, bufpoi);
  798.       putstr( ">  ", bufpoi );
  799. #else
  800.       putstr("  <-->  ", bufpoi);        /* Verbindung steht         */
  801. #endif
  802.       putuse('R', (ptcrdp +1)->luserl, (ptcrdp +1)->lusert, bufpoi);
  803.                         /* rechte Seite             */
  804.      }
  805.    }
  806.   for (userp = (usrtyp *) usccpl.lnext;        /* nun die User am CCP         */
  807.        (usrtyp *) &usccpl != userp;        /* bis zum Ende der Liste    */
  808.        userp = userp->unext)
  809.    {
  810.     putchr('\15', bufpoi);            /* neue Zeile je User         */
  811.     bufpoi->l4time = bufpoi->putcnt;        /* Zeichen im Buffer merken  */
  812.     putuse('L', userp->cblk_u, userp->typ_u, bufpoi); /* immer links         */
  813.     if (userp->status == 2)            /* Connect laeuft?         */
  814.      {
  815.       putspa(35, bufpoi);            /* Trennung             */
  816.       putstr("  <..>  ", bufpoi);        /* Verbindung wartet         */
  817.       if ((userp->typ_p == 2)            /* wird L2 Verbindung?         */
  818.         &&((ucblk = userp->cblk_p)->state == 0)) /* Status: connect laeuft   */
  819.        {
  820.         putstr("CQ(", bufpoi);            /* Partner ist "CQ"         */
  821.         putid(ucblk->srcid, bufpoi);
  822.         putchr(')', bufpoi);
  823.        }
  824.       else                    /* andere L2 Verbindung         */
  825.         putuse('R', userp->cblk_p, userp->typ_p, bufpoi);
  826.      }
  827. #ifdef TALKCMD
  828.      if( userp->status == 4 )            /* if user is in TALK mode   */
  829.      {
  830.          putspa( 35, bufpoi );            /* then print appropriate    */
  831.          putstr("  <-->  Talk", bufpoi );        /* message showing it        */
  832.      }
  833. #endif
  834.    }
  835.   seteom(bufpoi);                /* Ende der Meldung setzen   */
  836.   }
  837.